package com.example.demo.utils;


import com.alibaba.fastjson.JSONObject;
import com.example.demo.utils.model.CertResponse;
import com.example.demo.utils.model.CertResponseListBody;
import com.example.demo.utils.model.Resource;
import com.wechat.pay.contrib.apache.httpclient.WechatPayHttpClientBuilder;
import com.wechat.pay.contrib.apache.httpclient.auth.AutoUpdateCertificatesVerifier;
import com.wechat.pay.contrib.apache.httpclient.auth.PrivateKeySigner;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Credentials;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Validator;
import com.wechat.pay.contrib.apache.httpclient.util.PemUtil;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.GeneralSecurityException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.List;


/**
 * 用来获取平台证书的工具
 *
 * @author xueyj
 * @date 10:19 2021/1/4
 */
public class PZCutils {
    /**
     * 商户号
     */
    private final static String MAC_HID = "3333333333";
    /**
     * api3密钥
     */
    public final static String API3 = "3333333333333333333333333333";
    /**
     * 商户证书序列号
     */
    private final static String SERIAL_NO = "3333333333333333333333333333";

    /**
     * 微信获取证书接口
     */
    private final static String CERT_URL = "https://api.mch.weixin.qq.com/v3/certificates";

    /**
     * 申请交易账单接口
     * 对账单接口只能下载三个月以内的账单。
     */
    private final static String TRAN_BILL = "https://api.mch.weixin.qq.com/v3/bill/tradebill";

    /**
     * 商户证书私钥字符串
     */
    private final static String PRIVATEKEY = "-----BEGIN PRIVATE KEY-----\n" +
            "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCtEnvveeHyfT+1\n" +
            "vReQwT6DWnbjtS4vwjb4wVn8p4EuKIRZw5SGb4SKbpxfFaF5lcko8ZWehDRU/8Zv\n" +
            "WQuAs5jfkgBDdmuLbmn5rFy6w+NcOjSRnP0H7uzbFdF94imGNi/nJBBrK7eFtfcK\n" +
            "s7/CpdWO5pHPERx8RCAEeijfcgSBIrc7sP3L0cKDTfNauv7c0BgR+k9sOjtLu08U\n" +
            "fZ3SZzalAuHAjaR7mElE9fXXF5tA2KoQYbZkBtMhPkgbtPSVGe122FNM4C0sjQ4c\n" +
            "jq6W4UD+vmpOqxSMtxhFqqROCB1P/PFjtaFJaw5pGeIiWPhzeuZ2JVkaw9M5IlXu\n" +
            "qNPO6qUdAgMBAA33333333333333333333333333334LZRNJpGbhtBLBiqKdDrTFJf\n" +
            "j/JJQq95xzyQ3D9vWToMJu2/eplo60u44RKXR3pwRuErWMj8Q2EDjbX4R7K85+ni\n" +
            "VWyMOA8luML9jsClKXik4q9uvAaEwloRQwe7hVuSssxLk5HIM0pFaLlLt4UnH2+T\n" +
            "Jeqsh9rAURQYkH3333333333333333333333333333aLFx6qo5Ft/IVPFWXsQGNk\n" +
            "GQbCRL560kmyXU3XIzrdNm3B+uUy2aFbHLM82LjWAQKBgQDgpfrU8PHeyMjfK/Mr\n" +
            "6WOhmrkk4GSvt7CvbeCDWlHUppj3O/yn/aYTpsd23Pg1nKkDP4+71i93Vw5qDbJD\n" +
            "6FpLJXWcH6LUEesPYdnrgAC77R/YKcfsVDGmNklkfGlsd4ut19LJKybCaqXLwVGm\n" +
            "EXp3badsFKKnc98vDdn0rhXmiQKBgQDFOddTmoD06c2EgK6hq0WBAP8a0yPozl/e\n" +
            "qLafXafqVbO0drrKLGoVf1KvOQoxZ2cw6lthM7LdoMPn+9pWICHK90p+VUBAlhsE\n" +
            "eJ6Bz06jl8UcCmU9BH1Mp9G3pRhHquNyvW8e4yv7Royv4yW36FMNsuTRZny8mF7W\n" +
            "nIEHxMvk9QKBgQCcGVmBS+eVmclSofR4B9XOPnf2MuJj420niV8fhswjypux+AHp\n" +
            "LWyQbSxe4M6sWi5q7mjO6db3333333333333333333333333333QzQBHtrk+durieZifa8\n" +
            "tghF6aT36SdMUolBhB2Y4Z4uK/MG8U7t6WlCwXQ7ut8HIpHr3WEdDzZymQKBgHZK\n" +
            "Mc6v7UZ3cE9XiuXmPqKYAWmKV5BLLw7xq867snmG+2hyiae2qc3I9sOnd2iYNzkM\n" +
            "ZtBO3Km2walC0foz/XCpjyFkakwSe5Pb8F21A9p0rcEarwvAxJIUWWFHAOADK7Xm\n" +
            "zl39LKTh9I3333333333333333333333333SDiR9AoGAUs4K3QER1h4MP54K+xXg\n" +
            "J7ovGwDhrV05fklYH1rlGc/KGYX3KCjrZ2we1KUPlwZ63U+z5Hb/W6NMrK8um5TS\n" +
            "mAIV6V6iQcZsxlOsjJD6t8wXle4CMG5YF0EcQVjk369jF2Dmv+D9jUrbDoIQO15I\n" +
            "WsjQOM+sjM2CIGZXxpLEVXs=\n" +
            "-----END PRIVATE KEY-----";

    /**
     * 通过微信接口获得的平台证书
     */
    private static final String PTZ_CERT = "-----BEGIN CERTIFICATE-----\n" +
            "MIID3DCCAsSgAwIBAgIUeMQsmARXdFE+malg0ToqvW6Iu4kwDQYJKoZIhvcNAQEL\n" +
            "BQAwXjELMAkGA1UEBhMCQ04xEzARBgNVBAoTClRlbnBheS5jb20xHTAbBgNVBAsT\n" +
            "FFRlbnBheS5jb20gQ0EgQ2VudGVyMRswGQYDVQQDExJUZW5wYXkuY29tIFJvb3Qg\n" +
            "Q0EwHhcNMjEwMTAzMDUxNTQ2WhcNMjYwMTAyMDUxNTQ2WjBuMRgwFgYDVQQDDA9U\n" +
            "ZW5wYXkuY29tIHNpZ24xEzARBgNVBAoMClRlbnBheS5jb20xHTAbBgNVBAsMFFRl\n" +
            "bnBheS5jb20gQ0EgQ3333333333333333333333333333p9XwjMpiWQftyK8P\n" +
            "1o6S+9azN96nmGoCytgEPSQgJwo4bgkzcDQnoxCmBOLy7br2okk/pO7eNuyAx3Hj\n" +
            "JUX0jAFlUQ9/8U7f+xog07bElM9cKWY6I5UloljUNcLWz4KoSVt9AMvhdNbi2Q/H\n" +
            "ORVBNLnuIQ8kxF4/UHo1LzPveSsQA1QDRAfa7kPIkQQawFVg94fsw4ApizevUhNy\n" +
            "22IUwXsi6L2EnnS1Xt0Q22kCwmwlKhTgH6WGZVaU6FaNY9mc7ir2RfP039YX8+O0\n" +
            "/XFpNOrHx1ySx1xwSK9y5FJHOBBzigVkXi4RCgSqz2l0rRotBtt9LlHonkh4EvHE\n" +
            "/tAJAgMBAAGjgYE3333333333333333333333333333ljL2l0cnVzY3Js\n" +
            "P0NBPTFCRDQyMjBFNTBEQkMwNEIwNkFEMzk3NTQ5ODQ2QzAxQzNFOEVCRDIwDQYJ\n" +
            "KoZIhvcNAQELBQADggEBAHPns6OTZExZ11VGLEp8xDdNE9k1HEYT1S4seCXRlUJu\n" +
            "Q2VLMMl1z3333333333333333333333333333cXNbti9WI6TZtzSAMnWeOwkRZ+rg4DDdh\n" +
            "gJ5eYj4YK8p/+EFQU4oXVhRXkXKl7dHfZQfbliI4/2AlogywyrMIDAr9A3GxFkxw\n" +
            "CsFzQ6RofIrHhJovvn8sftDLxaYPgTgjcyM6csl3z+dZXegxw8XqR+a4agT3OSRI\n" +
            "ymcC8WD13m5YlodJBAr/WvQnlxiKUL78yfSSWQf2GiJShnnQm7Tb5uL4njMF7ncW\n" +
            "zZF6amz3HJaVEly2PHUAQX0Ubr+lj3B5O6t+C4fOzbs=\n" +
            "-----END CERTIFICATE-----";

    /**
     * 通过linux命令获得的平台证书公钥
     */
    private static final String PTZ_PUB_KEY = "-----BEGIN PUBLIC KEY-----\n" +
            "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0qfV8IzKYlkH7civD9aO\n" +
            "kvvWszfep53333333333333333333333333333QDL4XTW4tkPxzkV\n" +
            "QTS57iEPJMReP1B6NS8z73krEANUA0QH2u5DyJEEGsBVYPeH7MOAKYs3r1ITctti\n" +
            "FMF7Iui9hJ50tV7dENtpAsJsJSoU4B+lhmVWlOhWjWPZnO4q9kXz9N/WF/PjtP1x\n" +
            "aTTqx8dcksdccEivcuRSRzgQc4oFZF4uEQoEqs9pdK0aLQbbfS5R6J5IeBLxxP7Q\n" +
            "CQIDAQAB\n" +
            "-----END PUBLIC KEY-----";

    public static CloseableHttpClient wxClient() {
        // 加载商户私钥（privateKey：私钥字符串）
        PrivateKey merchantPrivateKey = PemUtil
                .loadPrivateKey(new ByteArrayInputStream(PRIVATEKEY.getBytes(StandardCharsets.UTF_8)));

        // 加载平台证书（mchId：商户号,mchSerialNo：商户证书序列号,apiV3Key：V3秘钥）
        AutoUpdateCertificatesVerifier verifier = new AutoUpdateCertificatesVerifier(
                new WechatPay2Credentials(MAC_HID, new PrivateKeySigner(SERIAL_NO, merchantPrivateKey)), API3.getBytes(StandardCharsets.UTF_8));

        // 初始化httpClient
        return WechatPayHttpClientBuilder.create()
                .withMerchant(MAC_HID, SERIAL_NO, merchantPrivateKey)
                .withValidator(new WechatPay2Validator(verifier)).build();
    }

    /**
     * 获取证书主方法
     *
     * @param index 第几个证书   第一个是0
     */
    public static String getPlatCert(int index) throws IOException, GeneralSecurityException {
        CloseableHttpClient client = PZCutils.wxClient();
        HttpGet get = new WxPayV3Util().postHeader(new HttpGet(CERT_URL));
        CloseableHttpResponse response = client.execute(get);
        HttpEntity resEntity = response.getEntity();
        String g1 = EntityUtils.toString(resEntity, StandardCharsets.UTF_8);
        client.close();
        response.close();
        CertResponse certResponse = JSONObject.parseObject(g1, CertResponse.class);
        /*获得了数组第一个证书*/
        List<CertResponseListBody> data = certResponse.getData();
        int size = data.size();
        if (index + 1 > size) {
            return "共" + size + "个证书,index过大";
        }
        Resource resource = data.get(index).getEncrypt_certificate();

        AesUtil aesUtil = new AesUtil(PZCutils.API3.getBytes(StandardCharsets.UTF_8));
        return aesUtil.decryptToString(resource.getAssociated_data().getBytes(StandardCharsets.UTF_8),
                resource.getNonce().getBytes(StandardCharsets.UTF_8),
                resource.getCiphertext());

        /*
         * 获得平台证书后通过
         * linux命令获取证书公钥
         * openssl x509 -in wxpay_cert.pem -pubkey -noout > wxpay_public_key.pem
         * */

    }

    public static PublicKey getPtzPub() throws CertificateException {
        byte[] bytes = PTZ_CERT.getBytes(StandardCharsets.UTF_8);
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);

        PublicKey pk = null;
        ByteArrayInputStream bais = null;
        CertificateFactory certificatefactory = CertificateFactory.getInstance("X.509");
        bais = byteArrayInputStream;
        X509Certificate cert = (X509Certificate) certificatefactory.generateCertificate(bais);
        return cert.getPublicKey();
    }

    /*   public static void main(String[] args) throws GeneralSecurityException, IOException {
           WxPayV3Util wxPayV3Util = new WxPayV3Util();
           PublicKey ptzPub = wxPayV3Util.getPtzPub();
           String WechatpayTimestamp = "1609924499";
           String WechatpayNonce = "yRChorZfiw05tKmFZTng3hLq4YG3khId";
           String WechatpaySignature = "VwrrkWEN4fQjmqefe4Pr1wnRxXUsm/8FJCEk/BNDizrdyU1KdEev1Jmiv/VGkovLg5DU1b/zT0hyQEtSBuWPNjzKWk+OOyf+AXKsq4WTR/wOV2MqH8AT5zqLifVJ3lAgQlE+m0FBoSMApdsaqA4yZE7lZq0EAtCfNSBABvso6QroCyo5qW/opYiXsaSkeK3e2M38VIJUzJoD9agOx7NZqhLAf04frYYC33my82s2NvdFLAuuA1XjU3s2SAc90an0/l/PmcdQQVyrFPMsKEosAjFZJiwNWOJLTHUvHlcgABRT8D4caBKRsBBg8nStrlytuTxL7R2YVVhsHO366TSvgg==";
           String body = "{\"id\":\"451f1714-b063-51ce-8e8b-efd001b84a46\",\"create_time\":\"2021-01-06T17:14:59+08:00\",\"resource_type\":\"encrypt-resource\",\"event_type\":\"TRANSACTION.SUCCESS\",\"summary\":\"支付成功\",\"resource\":{\"original_type\":\"transaction\",\"algorithm\":\"AEAD_AES_256_GCM\",\"ciphertext\":\"Ty6qhJdyokgg8hGlJSk1xwrZ2lnenVIGoTy8tX7RDEYz9/O2MS0/D3SoF0OuFcZd04GAnz6aVHupuaFsdHV/vpJdaU1mFzvr1LFrWwaeMpJB4Yld0B1O71SqzWFnGUGt2S0COg2cipaWT41wgFrwG2mCc7ijQ1l4wumxZYliLmhq8liYMb58td1eP5W8pf9p2KPcpDlwyCG7NrYZ/6Qud0SR0H0YCet3LwjHhZc880uZgBNhFZbTmyWgWs/09mMePWl+Mh3wrbBt7xCvH2fEr6dWwTuf7qfkfIxMIJAq9boh2fzxqgfbbOeAY/h/V0TkxIA9OaXAlYnn3AEgr6176OVAappMyxx0LnoCN3SSfWi2WvLkW3N8y5Ix1Ii2kg/lEJGVmW1ppvKn02ntcVUGZSJJUuzuDxYiWfLYXCrnWqRXIRogdWgQtEvchtX7l8/y4ubnPLUmIqh0rwwkaZ8cEp2aUk0hsG+TcV2HOzFMKTzhYlJ1oFiZERGp23CuxZpRrHBJbPNpiyoUUQBlmm6QsuhyrzG/PDfsvfrIaEgxBMnQr2ISTy35HwghDIF8PBcbgTYT\",\"associated_data\":\"transaction\",\"nonce\":\"5usVPJeb1aNG\"}}";
           String srcData = WechatpayTimestamp + "\n"
                   + WechatpayNonce + "\n"
                   + body + "\n";

           boolean verify = SignUtil.verify(srcData, WechatpaySignature, ptzPub);
           System.out.println(verify);
       }*/
    public String applyTranBill(String day) throws IOException {
        StringBuilder url = new StringBuilder(TRAN_BILL);
        url.append("?bill_date=")
                .append(day);
        CloseableHttpClient client = wxClient();
        HttpGet get = new WxPayV3Util().postHeader(new HttpGet(url.toString()));
        CloseableHttpResponse response = client.execute(get);
        HttpEntity resEntity = response.getEntity();
        String g1 = EntityUtils.toString(resEntity, StandardCharsets.UTF_8);
        client.close();
        response.close();
        return g1;
    }

    /*public static void main(String[] args) throws IOException {
        String s = new PZCutils().applyTranBill("2021-01-07");
        System.out.println(s);
        JSONObject jsonObject = JSONObject.parseObject(s);
        String download_url = jsonObject.getString("download_url");
        CloseableHttpClient closeableHttpClient = wxClient();
        HttpGet httpGet = new WxPayV3Util().postHeader(new HttpGet(download_url));
        CloseableHttpResponse execute = closeableHttpClient.execute(httpGet);
        closeableHttpClient.close();
    }*/
}



